﻿using Model.CommonEntities;
using Model.StrategyEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BLL
{
    public sealed partial class AnalysisEngine
    {
        /*
         * MID:=(3*CLOSE+LOW+OPEN+HIGH)/6;
        牛线:(20*MID+19*REF(MID,1)+18*REF(MID,2)+17*REF(MID,3)+16*REF(MID,4)+15*REF(MID,5)
        +14*REF(MID,6)+13*REF(MID,7)+12*REF(MID,8)+11*REF(MID,9)+10*REF(MID,10)
        +9*REF(MID,11)+8*REF(MID,12)+7*REF(MID,13)+6*REF(MID,14)+5*REF(MID,15)+4*REF(MID,16)
        +3*REF(MID,17)+2*REF(MID,18)+REF(MID,20))/211;
        马线:MA(牛线,5),COLORGREEN;
        乖离率:(C-牛线)/牛线*100;
         */
        public static ZNFZXResult ZNFZX(SortedList<string, SingleStockStru> stocklist, int period = 0)
        {
            List<decimal> MIDList = new List<decimal>();
            //时间列表
            List<decimal> TList = new List<decimal>();
            //收盘价列表
            List<decimal> CloseList = new List<decimal>();
            //开盘价列表
            List<decimal> OpenList = new List<decimal>();
            //最高价列表
            List<decimal> HighList = new List<decimal>();
            //最低价列表
            List<decimal> LowList = new List<decimal>();
            //牛线
            List<decimal> CowList = new List<decimal>();
            //马线
            List<decimal> HorseList = new List<decimal>();
            //买入基准价
            List<decimal> arg = new List<decimal>();

            //MID:=(3*CLOSE+LOW+OPEN+HIGH)/6;
            foreach (var item in stocklist)
            {
                MIDList.Add((3 * item.Value.close + item.Value.high + item.Value.low + item.Value.open) / 6);
            }
            
            //计算均值时，取值向前偏移的长度，最长要计算5日均值，所以要向前再取4个值
            int shift = 4;
            //实际取值周期长度 = 计算周期长度 + 向前偏移长度
            period += shift;
            //根据给定显示周期period，逆时序截取period条数据：D、K线，Time，开盘价，收盘价，最高价，最低价
            if (MIDList.Count > period)
            {
                for (int i = 0; i < period; i++)
                {

                    CowList.Add((20 * REF(MIDList, i) + 19 * REF(MIDList, i + 1) + 18 * REF(MIDList, i + 2) + 17 * REF(MIDList, i + 3) + 16 * REF(MIDList, i + 4)
                        + 15 * REF(MIDList, i + 5) + 14 * REF(MIDList, i + 6) + 13 * REF(MIDList, i + 7) + 12 * REF(MIDList, i + 8) + 11 * REF(MIDList, i + 9)
                        + 10 * REF(MIDList, i + 10) + 9 * REF(MIDList, i + 11) + 8 * REF(MIDList, i + 12) + 7 * REF(MIDList, i + 13) + 6 * REF(MIDList, i + 14)
                        + 5 * REF(MIDList, i + 15) + 4 * REF(MIDList, i + 16) + 3 * REF(MIDList, i + 17) + 2 * REF(MIDList, i + 18) + REF(MIDList, i + 20)) / 211);

                    TList.Add(Convert.ToDecimal(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1]));
                    CloseList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].close);
                    OpenList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].open);
                    HighList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].high);
                    LowList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].low);
                }
                //马线:MA(牛线,5)
                HorseList = SMA_Reverse(CowList, 5).Values;
                CowList.RemoveRange(CowList.Count - 4, 4);
                TList.RemoveRange(TList.Count - 4, 4);
                CloseList.RemoveRange(CloseList.Count - 4, 4);
                OpenList.RemoveRange(OpenList.Count - 4, 4);
                HighList.RemoveRange(HighList.Count - 4, 4);
                LowList.RemoveRange(LowList.Count - 4, 4);
            }
            else
            {
                for (int i = 0; i < MIDList.Count; i++)
                {

                    CowList.Add((20 * REF(MIDList, i) + 19 * REF(MIDList, i + 1) + 18 * REF(MIDList, i + 2) + 17 * REF(MIDList, i + 3) + 16 * REF(MIDList, i + 4)
                        + 15 * REF(MIDList, i + 5) + 14 * REF(MIDList, i + 6) + 13 * REF(MIDList, i + 7) + 12 * REF(MIDList, i + 8) + 11 * REF(MIDList, i + 9)
                        + 10 * REF(MIDList, i + 10) + 9 * REF(MIDList, i + 11) + 8 * REF(MIDList, i + 12) + 7 * REF(MIDList, i + 13) + 6 * REF(MIDList, i + 14)
                        + 5 * REF(MIDList, i + 15) + 4 * REF(MIDList, i + 16) + 3 * REF(MIDList, i + 17) + 2 * REF(MIDList, i + 18) + REF(MIDList, i + 20)) / 211);

                    TList.Add(Convert.ToDecimal(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1]));
                    CloseList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].close);
                    OpenList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].open);
                    HighList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].high);
                    LowList.Add(stocklist[Convert.ToString(stocklist.Keys.ToList<string>()[stocklist.Count - i - 1])].low);
                }
                //马线:MA(牛线,5)
                HorseList = SMA_Reverse(CowList, 5).Values;
                CowList.RemoveRange(CowList.Count - 4, 4);
                TList.RemoveRange(TList.Count - 4, 4);
                CloseList.RemoveRange(CloseList.Count - 4, 4);
                OpenList.RemoveRange(OpenList.Count - 4, 4);
                HighList.RemoveRange(HighList.Count - 4, 4);
                LowList.RemoveRange(LowList.Count - 4, 4);
            }

            CowList.Reverse();
            //HorseList.Reverse();
            TList.Reverse();
            CloseList.Reverse();
            OpenList.Reverse();
            HighList.Reverse();
            LowList.Reverse();

            //基准价取开盘价和收盘价的中值
            for (int i = 0; i < CloseList.Count; i++)
            {
                arg.Add((CloseList[i] + OpenList[i]) / 2);
            }

            var result = new ZNFZXResult
            {
                StockCode = stocklist.First().Value.code,
                ShortList = CowList,
                LongList = HorseList,
                TList = TList,
                CloseList = CloseList,
                OpenList = OpenList,
                HighList = HighList,
                LowList = LowList,
                BenchmarkList = CloseList
            };

            return result;
        }
    }
}
